package de.pyranja.timing;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Strings.emptyToNull;

import javax.annotation.concurrent.Immutable;

/**
 * <p>Represents a point in time.</p>
 * @author Chris Borckholder
 */
@Immutable
public class Moment implements Comparable<Moment> {
	
	private final long time;
	private final String title;
	
	public Moment(long time, String title) {
		super();
		this.time = time;
		this.title = checkNotNull(emptyToNull(title), "Must specify a non-empty title");
	}
	
	/**
	 * <p>Moments are ordered by their time value.</p>
	 * <p><strong>Note:</strong>This class has a natural ordering that is 
	 * inconsistent with equals, as equality also considers contextual 
	 * informations associated with a moment.</p>
	 * {@inheritDoc}
	 * @param that another {@link Moment}
	 */
	@Override
	public int compareTo(Moment that) {
		checkNotNull(that,"Cannot compare to null Moment");
		if (this == that) { 
			return 0; 	// shortcut
		} else {
			return Long.compare(this.time, that.time);
		}
	}

	/**
	 * @return the time
	 */
	public long getTime() {
		return time;
	}

	/**
	 * @return the title
	 */
	public String getTitle() {
		return title;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "Moment [time=" + time + ", title=" + title + "]";
	}
	
	/**
	 * Creates a JSON representation of this moment.
	 * @return String containing the JSON representation
	 */
	public String toJSON() {
		StringBuilder json = new StringBuilder();
		json.append("{ ")
			.append("\"title\" : \"").append(title).append("\", ")
			.append("\"time\" : ").append(time)
			.append(" }");
		return json.toString();
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + (int) (time ^ (time >>> 32));
		result = prime * result + ((title == null) ? 0 : title.hashCode());
		return result;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Moment other = (Moment) obj;
		if (time != other.time)
			return false;
		if (title == null) {
			if (other.title != null)
				return false;
		} else if (!title.equals(other.title))
			return false;
		return true;
	}
}
